home *** CD-ROM | disk | FTP | other *** search
- /* makemovy.c
-
- This program demonstrates the use of Turbo C to make a short movie
- (containing only ten frames) which can be viewed using ANIMATE.EXE.
- It also demonstrates single versus double buffering of images.
- In this example, we show a simple traveling wave.
-
- This program can be compiled and executed as is,
- but, before you do that:
- 1. You need to place header file grafsupp.h in your \TURBOC\INCLUDE
- directory. grafsupp.h provides definitions and prototypes related
- to functions in grafsupp.c, which make possible device
- independent plotting, i.e. you don't have to worry about pixels.
- Routines in grafsupp.c are modeled after routines in graphics
- written at the National Center for Atmospheric Research (NCAR).
- 2. You need to create files HERC.OBJ and EGAVGA.OBJ using Borland's
- BGIOBJ utility before "making" an executable version of this
- program. Alternatively, you can delete the references to
- registerbgidriver() in this program and references to EGAVGA.OBJ
- and HERC.OBJ in MAKEMOVY.PRJ. See the Turbo C manuals
- for more information regarding BGIOBJ and registerbgidriver().
- 3. You need to select MAKEMOVY.PRJ as the project file.
-
- You may find that the functions in grafsupp.c:
-
- load_array(),
- scale(),
- draw_perimeter(),
- label_plot(),
- and plot_curve()
-
- are useful for your own Turbo C graphics.
-
- A useful function which I have not utilized in this program is
- gprintf(), which appears in Borland's bgidemo.c, which is part of the
- Turbo C package. gprintf() is modeled after printf() but prints
- while the screen is in graphics mode, making it very useful to label plots.
- I did not include the source for gprintf() because it is copyrighted.
- You can use gprintf() in your own programs, but you cannot legally distribute
- it in source code form because of the copyright.
- If we are lucky, the next version of Turbo C might make gprintf()
- a built-in function.
-
- Jon Ahlquist, 9 Feb 1989, 12 January 1990.
-
- Copyright 1990 by Jon Ahlquist, Department of Meteorology B-161,
- Florida State University, Tallahassee, Florida 32306-3034, USA.
- Telephone: (904) 644-1558.
- Telnet address: ahlquist@metsat.met.fsu.edu (ahlquist@128.186.5.2)
-
- This software may be freely copied without charge.
- Copyright is made to prevent anyone from trying to impose restrictions
- on this software.
- All software and documentation is provided "as is" without warranty
- of any kind.
-
- Development of this material was sponsored by NSF grant ATM-8714674.
- */
-
- /* Include statements. Prototypes for: */
- #include <io.h> /* open(), write() */
- #include <conio.h> /* clrscr(), getch() */
- #include <ctype.h> /* toupper() */
- #include <dos.h> /* delay() */
- #include <fcntl.h> /* O_RDWR, O_CREAT, O_BINARY */
- #include <graphics.h>/* All Borland graphics routines.*/
- #include <math.h> /* cos() */
- #include <stdio.h> /* printf(), scanf() */
- #include <stdlib.h> /* exit() */
- #include <sys\stat.h>/* S_IREAD, S_IWRITE */
- #include <grafsupp.h>/* scale(), XX(x), YY(y) */
- /* All header files but grafsupp.h are supplied with Turbo C.
- grafsupp.h was written by Jon Ahlquist to accompany
- the functions in grafsupp.c.
- */
-
- #define PI 3.14159265
- #define NPTS 200
-
- void main(void)
- {
- int graph_driver, graph_mode, graph_error,
- num_frames = 10, /* No. of pictures to form the movie. */
- page, /* Index for page of video memory, either 0 or 1. */
- handle, /* Handle for file which will hold the movie. */
- iframe, i, /* Loop indices. */
- num_bit_planes=1;
-
- float x[NPTS], xmin, xmax,
- y[NPTS], ymin, ymax,
- k, c, t, dt;
-
- char plotfile[81], /* Name of file to hold movie. */
- response; /* 'y', 'Y', 'n', or 'N' for yes or no. */
-
- /* We'll use a pointer, save_raster, to point to the version
- of save_raster that we want. */
- void (*save_raster) (int handle, int page, int num_bit_planes);
- void save_Herc_raster(int handle, int page, int num_bit_planes);
- void save_EGA_raster (int handle, int page, int num_bit_planes);
-
- /* Clear the screen, and print an introduction. */
- clrscr();
- printf(
- "This program demonstrates two things:\n"
- "1. using Turbo C to make a rasterized movie\n"
- " that can be viewed with ANIMATE, and\n"
- "2. single versus double buffering of video images.\n"
- "After the movie has been made, it can be viewed using ANIMATE.EXE.\n");
-
- /* Get user input. */
-
- printf("\nDo you want the movie to be made using EGA graphics?\n"
- "(If not, we'll use Hercules graphics.)\n");
- do {
- printf("Type 'y' or 'Y' for yes, 'n' or 'N' for no.\n"
- "Hit the Escape key if you want to abort this program.\n");
- response = toupper(getch());
- if (response == 27) exit(0);
- } while (! ((response=='Y') || (response=='N')));
-
- printf("\nName the file you want to hold the rasterized images.\n"
- "The file will occupy about 300 kilobytes.\n");
- scanf ("%s", plotfile);
-
- handle = open (plotfile, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY,
- S_IWRITE | S_IREAD);
- if (handle == -1)
- {
- printf("Unable to open the file.\n"
- "Perhaps you typed an illegal file name or your disc is full.\n");
- exit(1);
- }
-
- clrscr();
- printf(
- "The first half of the pictures will be drawn without double buffering,\n"
- "so you will see the drawing as it takes place.\n"
- "The second half of the movie will be created using double buffering.\n"
- "The motion will look smoother because\n"
- "you will not see an image until it is complete.\n\n"
- "Notes:\n"
- "1. The movie that is stored to disc is not affected by whether the images\n"
- " are created by single or double buffering.\n"
- " When you create a movie, you will probably prefer single buffering,\n"
- " because then you see everything as it is drawn,\n"
- " and that can help with debugging.\n"
- " When you view a finished movie, though, you will certainly want\n"
- " double buffering, such as is offered by ANIMATE.\n"
- "2. For Hercules graphics users only:\n"
- " When double buffering starts, you will see that Borland\n"
- " has a bug in its graphics screen clear command.\n"
- " This does not affect the images that are stored to disc, though,\n"
- " so your movie will look fine when viewed with ANIMATE.\n\n"
- "Hit any key to start making the movie.\n");
-
- getch();
-
-
- /* Define limits in space and time. */
- ymax = 1.0;
- xmin = 0.; xmax = 2.*PI;
- ymin = -1.0;
- k = 3.; /* wavenumber */
- c = 1.; /* phase speed */
-
- /* Set dt so that the movie will be one wave period long. */
- dt = 2. * PI / (k * c * num_frames);
-
-
- /* Initialize graphics. */
-
- if (response == 'Y')
- {
- graph_driver = EGA;
- graph_mode = EGAHI;
- save_raster = save_EGA_raster;
- }
- else
- {
- graph_driver = HERCMONO;
- graph_mode = HERCMONOHI;
- save_raster = save_Herc_raster;
- }
-
- if (registerbgidriver(EGAVGA_driver) < 0)
- {
- printf("Unable to register EGA/VGA graphics driver.");
- exit(1);
- }
- if (registerbgidriver(Herc_driver) < 0)
- {
- printf("Unable to register Hercules graphics driver.");
- exit(1);
- }
-
- initgraph (&graph_driver, &graph_mode, "\\turboc");
- if ((graph_error = graphresult()) < 0)
- {
- printf("Error while trying to initialize graphics.\n");
- printf("%s\n", grapherrormsg(graph_error));
- exit(1);
- }
-
- /* Set scaling factors to create device independent graphics,
- so that we do not have to count pixels.
- The eight arguments of scale() are explained in the comments
- at the beginning of scale().
- For users of NCAR graphics, the arguments for scale() are the same
- as the first eight arguments to Fortran subroutine SET
- of the NCAR graphics package. */
- scale( 0., 1., 0.25, 0.75, xmin, xmax, ymin, ymax);
-
-
- /* Load the x array. */
- load_array(x, NPTS, xmin, xmax);
-
-
- /* Make the movie frame by frame. */
- page = 0;
- for (iframe = 0, t = 0.; iframe < num_frames; iframe++, t += dt)
- {
- /* Use single buffering for the first half of the movie,
- then use double buffering. */
- if (iframe < (num_frames/2))
- page = 0; /* The first video page is page 0. */
- else /* Toggle the page between 0 & 1 for double buffering. */
- page = 1 - page;
-
- setactivepage(page);
- cleardevice();
-
- /* Draw a box around the plotting domain, add tick marks,
- and lable the plot. */
- draw_perimeter(4, 2, 2, 2);
- label_plot("Traveling wave", "x axis", "Wave amplitude");
-
- /* Load the y array. */
- for (i=0; i< NPTS; i++) y[i] = cos( k*(x[i]-c*t) );
-
- /* Plot the function. */
- plot_curve(x, y, NPTS);
-
- /* Display and save the plot. */
- setvisualpage(page);
- save_raster(handle, page, num_bit_planes);
- }
-
- closegraph();
- close (handle);
-
- printf(
- "To view the movie you have just made, type ANIMATE and hit the Enter key.\n"
- "Select 'r' for replay of rasterized images.\n"
- "Enter %s as the first file.\n"
- "Enter DONE as the second file.\n"
- "Answer no to the question about saving the movie.\n"
- "Then watch the movie.\n"
- "Note that the motion will look endless because the movie\n"
- "will be repeated until you hit the Escape key.\n\n"
- "Good luck!\n", plotfile);
- } /* End of main(). */
-
- /**********************************************************************/
-
- void save_Herc_raster(int handle_out, int page, int num_bit_planes)
-
- /* This function stores a Hercules image to disc in rasterized form,
- i.e. pixel by pixel.
-
-
- Variable Meaning
-
- handle_out Handle to the file to which the image will be written.
-
- page Video page to be saved, either 0 or 1.
-
- num_bit_planes Unused dummy variable included to provide consistency with
- save_EGA_raster().
-
-
- Jon Ahlquist, 22 July 1988, 1 Dec 1989.
- */
-
- {
- #define NBYTES_HERC 32768U /* Number of bytes in a Hercules image. */
-
- unsigned nbytes_written;
- void far *fptr;
-
- /* Define the address on the grahics board from which the image will
- be read. */
- fptr = page ? (void far *) 0xb8000000L : (void far *) 0xb0000000L;
-
- nbytes_written = _write(handle_out, fptr, NBYTES_HERC);
- if (nbytes_written < NBYTES_HERC)
- {
- closegraph();
- printf("Can't save image. Disc is probably full.\n");
- exit(1);
- }
- } /* End of save_Herc_raster().
- Don't worry about a compilation warning saying that num_bit_planes is never
- used. num_bit_planes is not needed by save_Herc_raster() and was included
- only so that the call to save_Herc_raster() would be like the call to
- save_EGA_raster, where num_bit_planes is required. */
-
- /**************************************************************************/
-
- void save_EGA_raster(int handle, int page, int num_bit_planes)
-
- /* This function stores an EGA image to disc in rasterized form,
- i.e. pixel by pixel.
-
- Variable: Meaning:
- handle Handle to the file to which the image will be written.
- page Video page to be saved, either 0 or 1.
- num_bit_planes Number of bit planes to store.
- Any value between 1 and 4, inclusive, is acceptable.
-
- Jon Ahlquist, 22 July 1988, 1 Dec 1989.
- */
-
- {
- #define ONE 0x01
- #define NBYTES_EGA 28000U /* Number of bytes in an EGA bit plane. */
-
- int bit_plane;
- unsigned nbytes_written;
- void far *fptr;
-
-
- /* Define the address on the grahics board from which the image will
- be read. */
- fptr = page ? (void far *) 0xa8000000L : (void far *) 0xa0000000L;
-
- /* Tell the graphics board that one or more bit planes will be read. */
- outportb(0x3ce, 4);
-
- /* Loop through the bit plane(s) and write the image to the output file. */
- for (bit_plane = 0; bit_plane < num_bit_planes; bit_plane++)
- {
- /* Toggle the bit plane from which the image will be taken. */
- outportb(0x3cf, bit_plane);
-
- /* Write the image to the output file. */
- nbytes_written = _write(handle, fptr, NBYTES_EGA);
- if (nbytes_written < NBYTES_EGA)
- {
- closegraph();
- printf("Can't save image. Disc is probably full.\n");
- exit(1);
- }
- }
- } /* End of save_EGA_raster(). */